﻿//-----------------------------------------------------------------------
// <copyright file="IMergeCellInternal.cs" company="LMT">
//     Copyright (c) by La Minh Thuận.
// </copyright>
// <author>thuanla1985@hotmail.com</author>
//-----------------------------------------------------------------------
namespace LMT.Forms
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;

    /// <summary>
    /// Instance of every cell in MergeGridViewTextColumn
    /// </summary>
    public class MergeGridViewTextBoxCell : DataGridViewTextBoxCell, IMergeCell, IMergeCellInternal
    {
        /// <summary>
        /// variable whether this instance is vertical merge with next.
        /// </summary>
        private bool isVMergeN;

        /// <summary>
        /// variable whether this instance is vertical merge with previous.
        /// </summary>
        private bool isVMergeP;

        /// <summary>
        /// variable whether this instance is horizontal merge with next.
        /// </summary>
        private bool isHMergeN;

        /// <summary>
        /// variable whether this instance is horizontal merge with previous.
        /// </summary>
        private bool isHMergeP;

        /// <summary>
        /// Initializes a new instance of the <see cref="MergeGridViewTextBoxCell"/> class.
        /// </summary>
        public MergeGridViewTextBoxCell() : base()
        {
        }

        #region IMergeCell Members

        /// <summary>
        /// Gets a value indicating whether this instance is vertical merge.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is vertical merge; otherwise, <c>false</c>.
        /// </value>
        public bool IsVMergeNext
        {
            get 
            { 
                return this.isVMergeN; 
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is vertical merge previous.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is vertical merge previous; otherwise, <c>false</c>.
        /// </value>
        public bool IsVMergePrevious
        {
            get 
            { 
                return this.isVMergeP; 
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is horizontal merge next.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is horizontal merge; otherwise, <c>false</c>.
        /// </value>
        public bool IsHMergeNext
        {
            get 
            { 
                return this.isHMergeN; 
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is horizontal merge previous.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is H merge previous; otherwise, <c>false</c>.
        /// </value>
        public bool IsHMergePrevious
        {
            get 
            { 
                return this.isHMergeP; 
            }
        }

        #endregion

        #region IMergeCellSetter Members

        /// <summary>
        /// Gets or sets a value indicating whether this instance is vertical merge.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is vertical merge; otherwise, <c>false</c>.
        /// </value>
        bool IMergeCellInternal.IsVMergeNext
        {
            get { return this.isVMergeN; }
            set { this.isVMergeN = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is vertical merge previous.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is vertical merge previous; otherwise, <c>false</c>.
        /// </value>
        bool IMergeCellInternal.IsVMergePrevious
        {
            get { return this.isVMergeP; }
            set { this.isVMergeP = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is horizontal merge next.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is horizontal merge; otherwise, <c>false</c>.
        /// </value>
        bool IMergeCellInternal.IsHMergeNext
        {
            get { return this.isHMergeN; }
            set { this.isHMergeN = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is horizontal merge previous.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is H merge previous; otherwise, <c>false</c>.
        /// </value>
        bool IMergeCellInternal.IsHMergePrevious
        {
            get { return this.isHMergeP; }
            set { this.isHMergeP = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is analyze merge.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is analyze merge; otherwise, <c>false</c>.
        /// </value>
        bool IMergeCellInternal.IsAnalyzeMerge { get; set; }

        #endregion

        /// <summary>
        /// Sets the location and size of the editing panel hosted by the cell, and returns the normal bounds of the editing control within the editing panel.
        /// </summary>
        /// <param name="cellBounds">A <see cref="T:System.Drawing.Rectangle"/> that defines the cell bounds.</param>
        /// <param name="cellClip">The area that will be used to paint the editing panel.</param>
        /// <param name="cellStyle">A <see cref="T:System.Windows.Forms.DataGridViewCellStyle"/> that represents the style of the cell being edited.</param>
        /// <param name="singleVerticalBorderAdded">true to add a vertical border to the cell; otherwise, false.</param>
        /// <param name="singleHorizontalBorderAdded">true to add a horizontal border to the cell; otherwise, false.</param>
        /// <param name="isFirstDisplayedColumn">true if the cell is in the first column currently displayed in the control; otherwise, false.</param>
        /// <param name="isFirstDisplayedRow">true if the cell is in the first row currently displayed in the control; otherwise, false.</param>
        /// <returns>
        /// A <see cref="T:System.Drawing.Rectangle"/> that represents the normal bounds of the editing control within the editing panel.
        /// </returns>
        /// <exception cref="T:System.InvalidOperationException">
        /// The cell has not been added to a <see cref="T:System.Windows.Forms.DataGridView"/> control.
        /// </exception>
        public override Rectangle PositionEditingPanel(Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
        {
            MergeGridViewTextBoxColumn mergeCol = (MergeGridViewTextBoxColumn)this.DataGridView.Columns[this.ColumnIndex];
            MergeGridView gridView = (MergeGridView)this.DataGridView;
            
            // If all cell in merge block is editing at the same time
            if (mergeCol.MergeDirection != MergeDirection.None && mergeCol.IsMergeCellEditAll)
            {
                if (mergeCol.MergeDirection == MergeDirection.Vertical)
                {
                    Rectangle outLayout = gridView.FindMergeRowsDisplayArea(this.RowIndex, this.ColumnIndex);
                    if (!outLayout.IsEmpty)
                    {
                        return base.PositionEditingPanel(outLayout, outLayout, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
                    }
                }
                else if (mergeCol.MergeDirection == MergeDirection.Horizontal)
                {
                    Rectangle outLayout = gridView.FindMergeColumnsDisplayArea(this.RowIndex, this.ColumnIndex);
                    if (!outLayout.IsEmpty)
                    {
                        return base.PositionEditingPanel(outLayout, outLayout, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
                    }
                }
                else if (mergeCol.MergeDirection == MergeDirection.Both)
                {
                    Rectangle outLayout = gridView.FindMergeBothWayDisplayArea(this.RowIndex, this.ColumnIndex);
                    if (!outLayout.IsEmpty)
                    {
                        return base.PositionEditingPanel(outLayout, outLayout, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
                    }
                }
            }

            // Default setting editing panel of cell
            return base.PositionEditingPanel(cellBounds, cellClip, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
        }
    }
}
